//
// Created by ASUS on 2024/1/11.
//
#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int maxn=100005;

int a[maxn];
struct segmentTreeNode{
	int l,r;
	ll s;
	int lazy=0;
}t[4*maxn];

void pushup(int i){
	t[i].s=t[2*i].s+t[2*i+1].s;
}

void pushdown(int i){
	if(t[i].lazy){
		t[2*i].lazy+=t[i].lazy;
		t[2*i].s+=1ll*t[i].lazy*(t[2*i].r-t[2*i].l+1);
		t[2*i+1].lazy+=t[i].lazy;
		t[2*i+1].s+=1LL*t[i].lazy*(t[2*i+1].r-t[2*i+1].l+1);
		t[i].lazy=0;
	}
}

void build(int l,int r,int i){
	t[i].l=l;
	t[i].r=r;
	if(l==r){
		t[i].s=a[l];
		return;
	}
	int mid=l+(r-l)/2;
	build(l,mid,i*2);
	build(mid+1,r,i*2+1);
	pushup(i);
}

ll query(int l,int r,int i){
	if(t[i].l>r||t[i].r<l) return 0;
	if(t[i].l>=l&&t[i].r<=r){
		return t[i].s;
	}
	pushdown(i);
	return query(l,r,2*i)+query(l,r,2*i+1);
}

void update(int l,int r,int v,int i){
	if(t[i].l>r||t[i].r<l) return ;
	if(t[i].l>=l&&t[i].r<=r){
		t[i].lazy+=v;
		t[i].s+=1ll*v*(t[i].r-t[i].l+1);
		return;
	}
	pushdown(i);
	update(l,r,v,2*i);
	update(l,r,v,2*i+1);
	pushup(i);
}


int main(){
	int n,m,l,r,v,op;
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>a[i];
	build(1,n,1);
	while(m--){
		cin>>op;
		if(op==1){
			cin>>l>>r>>v;
			update(l,r,v,1);
		}else{
			cin>>l>>r;
			cout<<query(l,r,1)<<endl;
		}
	}
	return 0;
}